/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package muhnes.sizoo.vista;

import java.math.BigDecimal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.validator.ValidatorException;

public class CoordenadaConverter implements Converter {
    
    private final String patronDMS = "^(\\d{1,2})[°|º]([0-5][0-9]|60)'([0-5][0-9]\\.[0-9]|60)''(N|S|E|W)$";
    
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        
        validar( context, component, value );
        
        Object valorObject = null;
        
        if( value != null && !value.isEmpty() ) {
            Pattern patron = Pattern.compile( patronDMS );
            Matcher comparador = patron.matcher( value );
            System.out.print("comparador" +"patron"+patron+"va"+value+"c"+comparador);
            if( comparador.matches() ) {
                int grados = Integer.parseInt(comparador.group(1));
                System.out.print("g"+ grados);
                int minutos = Integer.parseInt(comparador.group(2));
                System.out.print("am"+ minutos);
                float segundos = Float.valueOf(comparador.group(3));
                System.out.print("s"+ segundos);
                String hemisferio = comparador.group(4);
                
                float coordenadaDecimal = grados + ((minutos * 60 + segundos) / (float)3600);
                int signo = hemisferio.equals("S") || hemisferio.equals("W") ? -1 : 1;
                valorObject = (coordenadaDecimal * signo);
                
            }
        }
        
        return valorObject;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        String valorString = "";
        
        float coordenadaDecimal = Math.abs(((BigDecimal)value).floatValue());
        float grados = (float)Math.floor( coordenadaDecimal );
        float minutos = (coordenadaDecimal % grados) * 60;
        float segundos = minutos == 0 ? 0 : (minutos % (float)Math.floor( minutos )) * 60;
        valorString += (grados < 10 ? "0" : "") + (int)(grados) + "°"; 
        valorString += (minutos < 10 ? "0" : "") + (int)(minutos) + "'";
        valorString += (segundos < 10 ? "0" : "") +  Math.rint((float)(segundos)) + "''";
           
        String tipoCoordenada = (String)component.getAttributes().get("tipo");
        
        if( tipoCoordenada != null && !tipoCoordenada.isEmpty() ) {
            if( tipoCoordenada.equalsIgnoreCase("latitud") ) {
                valorString += coordenadaDecimal < 0 ? "S" : "N";
            }
            else if( tipoCoordenada.equalsIgnoreCase("longitud") ) {
                valorString += ((BigDecimal)value).floatValue() < 0 ? "W" : "E";
            }
        }
        else {
            valorString = (((BigDecimal)value).floatValue() < 0 ? "-" : "") + valorString;
        }
        
        return valorString;
    }
    
    void validar(FacesContext contexto, UIComponent componente, Object valor)
        throws ValidatorException {
        
        String opc = (String) componente.getAttributes().get("opcional");
        boolean opcional = opc != null && !opc.isEmpty() ? Boolean.parseBoolean(opc) : false;
         
        String coordenada = String.valueOf(valor);
          
        System.out.print(valor+"valor");
        System.out.print(opcional + "hola");
        System.out.print(coordenada +"ddd");
        System.out.print(patronDMS);
        
        if( (coordenada == null || coordenada.isEmpty()) && !opcional ) {
            FacesMessage mensaje = new FacesMessage();
            mensaje.setSeverity( FacesMessage.SEVERITY_ERROR );
            mensaje.setSummary( "El campo no puede ser nulo." );
            mensaje.setDetail( "El campo es obligatorio y debe contener un valor." );
            contexto.addMessage( componente.getClientId(), mensaje );
            throw new ValidatorException( mensaje );
        }
        else if( !coordenada.matches( patronDMS ) && !opcional ) {
            FacesMessage mensaje = new FacesMessage();
            mensaje.setSeverity( FacesMessage.SEVERITY_ERROR );
            mensaje.setSummary( "El campo no tiene el formato adecuado." );
            mensaje.setDetail( "El valor debe ser una coordenada en formato DMS" );
            contexto.addMessage( componente.getClientId(), mensaje );
            throw new ValidatorException( mensaje );
        }
    }

}
